# language: zh-CN
# Epic 6.2: API版本管理
# 需求ID: REQ-006.2
# SRS需求: 系统应支持完整的API版本管理策略，包括URL路径、请求头、查询参数等多种版本控制方式，提供版本间的数据转换、兼容性检查、废弃管理、迁移支持和API契约管理
# Feature ID: FT-006.2
# 关联Epic: EP-006 (API层)
# 优先级: 高
# 复杂度: 中等

# 用户故事:
# US-078: 作为API开发者，我希望支持URL路径版本控制，以便通过URL路径区分不同版本的API
# US-079: 作为API开发者，我希望支持请求头版本控制，以便通过HTTP头指定API版本
# US-080: 作为API开发者，我希望支持查询参数版本控制，以便通过URL参数指定版本
# US-081: 作为API开发者，我希望支持语义化版本管理，以便规范化版本号和兼容性策略
# US-082: 作为API开发者，我希望支持字段级版本控制，以便精细化管理API字段变更和数据转换
# US-083: 作为API开发者，我希望支持API契约版本管理，以便管理API接口规范和文档

# 验收标准:
# - 支持多种版本控制策略：URL路径、请求头、查询参数
# - 实现语义化版本管理，支持主版本、次版本、补丁版本
# - 提供版本间的自动数据转换和字段映射
# - 支持API兼容性检查和破坏性变更检测
# - 实现版本废弃管理和迁移提醒机制
# - 支持字段级版本控制和精细化变更管理
# - 提供版本化的API文档和契约管理
# - 支持版本回退和灰度发布策略

功能: API版本管理
  为了支持API的演进和向后兼容
  作为API开发者
  我希望系统提供完整的版本管理功能

  背景:
    假设我是一个API开发者
    并且我需要管理API的多个版本
    并且我需要确保向后兼容性
    并且我需要支持平滑的版本迁移

  # US-078: 作为API开发者，我希望支持URL路径版本控制，以便管理不同版本的API端点
  场景: URL路径版本控制
    假设我使用URL路径进行版本控制
    当我定义多版本API时:
      """
      // v1版本的用户API
      @api({
        version: 'v1',
        path: '/api/v1/users',
        deprecated: false
      })
      entity User {
        id: string @primary
        name: string @required
        email: string @unique
      }
      
      // v2版本的用户API（添加了新字段）
      @api({
        version: 'v2',
        path: '/api/v2/users',
        deprecated: false
      })
      entity User {
        id: string @primary
        firstName: string @required  // 拆分name字段
        lastName: string @required
        email: string @unique
        phone: string @optional      // 新增字段
        
        // 向后兼容映射
        @computed
        name: string @getter(() => `${firstName} ${lastName}`)
      }
      """
    那么应该生成对应的版本化路由:
      """
      // v1 API路由
      GET    /api/v1/users
      POST   /api/v1/users
      GET    /api/v1/users/:id
      PUT    /api/v1/users/:id
      DELETE /api/v1/users/:id
      
      // v2 API路由
      GET    /api/v2/users
      POST   /api/v2/users
      GET    /api/v2/users/:id
      PUT    /api/v2/users/:id
      DELETE /api/v2/users/:id
      """
    并且应该支持版本间的数据转换
    并且应该维护版本特定的文档
    并且应该支持版本废弃警告

  # US-079: 作为API开发者，我希望支持请求头版本控制，以便通过HTTP头指定API版本
  场景: 请求头版本控制
    假设我使用请求头进行版本控制
    当客户端指定API版本时:
      """
      // 客户端请求
      GET /api/users
      Accept: application/vnd.myapi.v2+json
      API-Version: 2.1
      """
    那么应该根据请求头路由到正确版本:
      """
      {
        "requestHeaders": {
          "Accept": "application/vnd.myapi.v2+json",
          "API-Version": "2.1"
        },
        "resolvedVersion": {
          "major": 2,
          "minor": 1,
          "patch": 0,
          "handler": "UserControllerV2",
          "schema": "UserSchemaV2"
        },
        "responseHeaders": {
          "API-Version": "2.1",
          "Supported-Versions": "1.0, 1.1, 2.0, 2.1",
          "Deprecated-Versions": "1.0"
        }
      }
      """
    并且应该支持版本协商
    并且应该返回版本信息头
    并且应该处理不支持的版本请求

  # US-080: 作为API开发者，我希望支持查询参数版本控制，以便通过URL参数指定版本
  场景: 查询参数版本控制
    假设我使用查询参数进行版本控制
    当客户端通过查询参数指定版本时:
      """
      GET /api/users?version=2.0&format=extended
      """
    那么应该解析版本参数:
      """
      {
        "version": "2.0",
        "format": "extended",
        "resolvedConfig": {
          "apiVersion": "2.0",
          "responseFormat": "extended",
          "includeMetadata": true,
          "includeDeprecatedFields": false
        }
      }
      """
    并且应该支持版本特定的响应格式
    并且应该验证版本参数的有效性
    并且应该提供版本参数的默认值

  # US-081: 作为API开发者，我希望支持语义化版本管理，以便规范化版本号和兼容性
  场景: 语义化版本管理
    假设我使用语义化版本号
    当我定义API版本时:
      """
      @apiVersion({
        version: '2.1.3',
        compatibility: {
          backward: ['2.0.0', '2.1.0', '2.1.1', '2.1.2'],
          forward: ['2.1.4', '2.2.0']
        },
        lifecycle: {
          status: 'stable',
          releaseDate: '2024-01-15',
          deprecationDate: null,
          sunsetDate: null
        }
      })
      """
    那么应该管理版本兼容性:
      """
      {
        "versionMatrix": {
          "1.0.0": {
            "status": "deprecated",
            "sunsetDate": "2024-06-01",
            "migrationPath": "2.0.0"
          },
          "1.1.0": {
            "status": "deprecated",
            "sunsetDate": "2024-08-01",
            "migrationPath": "2.1.0"
          },
          "2.0.0": {
            "status": "maintenance",
            "supportUntil": "2024-12-31"
          },
          "2.1.3": {
            "status": "stable",
            "isLatest": true
          },
          "3.0.0-beta": {
            "status": "preview",
            "stableDate": "2024-03-01"
          }
        }
      }
      """
    并且应该支持版本生命周期管理
    并且应该提供版本迁移指南
    并且应该自动处理版本兼容性检查

  # US-082: 作为API开发者，我希望支持字段级版本控制，以便精细化管理API字段变更
  场景: 字段级版本控制
    假设我需要对字段进行版本控制
    当我定义字段版本时:
      """
      entity User {
        id: string @primary
        
        // v1字段
        name: string @required @since('1.0') @deprecated('2.0', 'Use firstName and lastName instead')
        
        // v2字段
        firstName: string @required @since('2.0')
        lastName: string @required @since('2.0')
        
        // v2.1字段
        middleName: string @optional @since('2.1')
        
        email: string @unique @required
        
        // v3预览字段
        socialProfiles: json @optional @since('3.0-beta') @experimental
      }
      """
    那么应该根据请求版本过滤字段:
      """
      // v1.0请求响应
      {
        "id": "user123",
        "name": "张三",
        "email": "zhang@example.com"
      }
      
      // v2.0请求响应
      {
        "id": "user123",
        "firstName": "三",
        "lastName": "张",
        "email": "zhang@example.com",
        "_deprecated": {
          "name": "This field is deprecated. Use firstName and lastName instead."
        }
      }
      
      // v2.1请求响应
      {
        "id": "user123",
        "firstName": "三",
        "lastName": "张",
        "middleName": null,
        "email": "zhang@example.com"
      }
      """
    并且应该支持字段废弃警告
    并且应该支持字段重命名映射
    并且应该支持实验性字段标记

  # US-083: 作为API开发者，我希望支持API契约版本管理，以便管理API接口规范
  场景: API契约版本管理
    假设我需要管理API契约
    当我定义API契约时:
      """
      @contract({
        version: '2.1',
        schema: {
          request: {
            body: 'CreateUserRequestV2',
            headers: ['Authorization', 'Content-Type'],
            queryParams: ['include', 'fields']
          },
          response: {
            success: 'UserResponseV2',
            error: 'ErrorResponseV2',
            headers: ['API-Version', 'Rate-Limit-Remaining']
          }
        },
        breaking_changes: [
          {
            version: '2.0',
            description: 'Split name field into firstName and lastName',
            migration: 'auto'
          }
        ]
      })
      """
    那么应该验证API契约兼容性
    并且应该生成契约文档
    并且应该支持契约测试
    并且应该检测破坏性变更
    并且应该提供迁移建议

  场景: 版本间数据转换
    假设我需要在版本间转换数据
    当处理不同版本的请求时:
      """
      // v1客户端发送的数据
      {
        "name": "张三",
        "email": "zhang@example.com"
      }
      
      // 转换为v2内部格式
      const v2Data = versionAdapter.transform(v1Data, {
        from: '1.0',
        to: '2.0',
        transformations: [
          {
            field: 'name',
            action: 'split',
            target: ['firstName', 'lastName'],
            separator: ' ',
            reverse: true  // 支持反向转换
          }
        ]
      });
      """
    那么应该自动转换数据格式:
      """
      // 转换后的v2格式
      {
        "firstName": "三",
        "lastName": "张",
        "email": "zhang@example.com"
      }
      """
    并且应该支持双向转换
    并且应该处理转换失败情况
    并且应该记录转换日志
    并且应该支持自定义转换规则

  场景: 版本废弃和迁移
    假设我需要废弃旧版本API
    当版本进入废弃期时:
      """
      @deprecated({
        version: '1.0',
        deprecatedSince: '2024-01-01',
        sunsetDate: '2024-06-01',
        migrationGuide: 'https://docs.api.com/migration/v1-to-v2',
        replacement: '2.0'
      })
      """
    那么应该在响应中添加废弃警告:
      """
      {
        "data": { ... },
        "_meta": {
          "version": "1.0",
          "deprecated": true,
          "deprecation": {
            "message": "API version 1.0 is deprecated and will be removed on 2024-06-01",
            "migrationGuide": "https://docs.api.com/migration/v1-to-v2",
            "replacement": "2.0",
            "daysUntilSunset": 120
          }
        }
      }
      """
    并且应该记录废弃版本的使用情况
    并且应该发送迁移通知
    并且应该提供迁移工具
    并且应该支持强制迁移

  场景: 版本监控和分析
    假设我需要监控版本使用情况
    当系统运行时
    那么应该收集版本使用统计:
      """
      {
        "versionUsage": {
          "1.0": {
            "requests": 1250,
            "uniqueClients": 45,
            "errorRate": 0.02,
            "avgResponseTime": 156,
            "trend": "decreasing"
          },
          "1.1": {
            "requests": 3420,
            "uniqueClients": 128,
            "errorRate": 0.015,
            "avgResponseTime": 142,
            "trend": "stable"
          },
          "2.0": {
            "requests": 8750,
            "uniqueClients": 234,
            "errorRate": 0.008,
            "avgResponseTime": 98,
            "trend": "increasing"
          }
        },
        "migrationProgress": {
          "from_1.0_to_2.0": {
            "totalClients": 45,
            "migratedClients": 32,
            "progress": 0.71,
            "estimatedCompletion": "2024-03-15"
          }
        }
      }
      """
    并且应该生成版本使用报告
    并且应该识别迁移阻塞因素
    并且应该提供版本优化建议
    并且应该支持版本使用告警

  场景: 客户端SDK版本管理
    假设我需要管理客户端SDK版本
    当生成客户端SDK时:
      """
      @sdkConfig({
        languages: ['typescript', 'python', 'java'],
        versions: {
          '1.0': {
            apiVersion: '1.0',
            features: ['basic_crud', 'authentication'],
            status: 'deprecated'
          },
          '2.0': {
            apiVersion: '2.0',
            features: ['basic_crud', 'authentication', 'advanced_queries'],
            status: 'stable'
          },
          '2.1': {
            apiVersion: '2.1',
            features: ['basic_crud', 'authentication', 'advanced_queries', 'real_time'],
            status: 'beta'
          }
        }
      })
      """
    那么应该生成版本化的SDK:
      """
      // TypeScript SDK v2.0
      export class UserApiV2 {
        constructor(config: ApiConfig) { ... }
        
        async getUser(id: string, options?: GetUserOptions): Promise<UserV2> {
          return this.client.get(`/api/v2/users/${id}`, {
            headers: { 'API-Version': '2.0' }
          });
        }
        
        async createUser(user: CreateUserRequestV2): Promise<UserV2> {
          return this.client.post('/api/v2/users', user, {
            headers: { 'API-Version': '2.0' }
          });
        }
      }
      """
    并且应该支持SDK版本兼容性检查
    并且应该提供SDK升级指南
    并且应该支持SDK自动更新

  场景: 版本测试和验证
    假设我需要测试版本兼容性
    当运行版本测试时:
      """
      describe('API Version Compatibility', () => {
        test('v1 client can still access basic user data', async () => {
          const response = await request(app)
            .get('/api/v1/users/123')
            .set('Accept', 'application/json')
            .expect(200);
            
          expect(response.body).toHaveProperty('name');
          expect(response.body).not.toHaveProperty('firstName');
        });
        
        test('v2 client gets enhanced user data', async () => {
          const response = await request(app)
            .get('/api/v2/users/123')
            .set('API-Version', '2.0')
            .expect(200);
            
          expect(response.body).toHaveProperty('firstName');
          expect(response.body).toHaveProperty('lastName');
        });
        
        test('deprecated version shows warning', async () => {
          const response = await request(app)
            .get('/api/v1/users/123')
            .expect(200);
            
          expect(response.headers).toHaveProperty('deprecation-warning');
        });
      });
      """
    那么应该验证版本兼容性
    并且应该测试数据转换正确性
    并且应该验证废弃警告
    并且应该测试版本协商
    并且应该生成兼容性测试报告